package com.sharemarking.system.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.sharemarking.system.dto.ExceptionType;
import com.sharemarking.system.dto.Page;
import com.sharemarking.system.entity.Permission;
import com.sharemarking.system.entity.User;
import com.sharemarking.system.exception.ApiException;
import com.sharemarking.system.mapper.PermissionMapper;
import com.sharemarking.system.mapper.RoleMapper;
import com.sharemarking.system.mapper.UserMapper;

@Controller
@RequestMapping("system/user")
public class UserController {
	@Autowired
	private UserMapper um;
	@Autowired
	private RoleMapper rm;
	@Autowired
	private PermissionMapper pm;
	@Autowired
	private PasswordEncoder pe;
	/**
	 * 用户管理列表页面
	 * @param search
	 * @param model
	 */
	@GetMapping("index")
	@PreAuthorize("hasPermission('base','all')")
	public void index(String name,Integer page,Model model){
		int size=10;
		if(page==null)page=0;
		List<User> userList=um.getPage(name, page*size, size);
		int total = um.getPageTotal(name);
		model.addAttribute("page", new Page<User>(page, size, total, userList));
		model.addAttribute("name", name);
	}
	/**
	 * 新增、编辑用户页面
	 * @param obj
	 * @param model
	 * @return
	 */
	@GetMapping("0")
	@PreAuthorize("hasPermission('base','all')")
	public String addPage(Model model){
		model.addAttribute("obj", new User());
		model.addAttribute("roles",rm.getAll());
		List<Permission> permissionList=pm.getAll();
		Set<String> domains=new HashSet<String>();
		for(Permission p:permissionList)domains.add(p.getDomain());
		model.addAttribute("domains", domains);
		model.addAttribute("permissions", permissionList);
		model.addAttribute("userRoleIds", new ArrayList<Integer>(0));
		model.addAttribute("userPermissionIds", new ArrayList<Integer>(0));
		return "system/user/form";
	}
	/**
	 * 新增、编辑用户页面
	 * @param obj
	 * @param model
	 * @return
	 */
	@GetMapping("{id}")
	@PreAuthorize("hasPermission('base','all')")
	public String get(@PathVariable("id")int id,Model model){
		User user=um.get(id);
		model.addAttribute("obj", user);
		model.addAttribute("roles",rm.getAll());
		List<Permission> permissionList=pm.getAll();
		Set<String> domains=new HashSet<String>();
		for(Permission p:permissionList)domains.add(p.getDomain());
		model.addAttribute("domains", domains);
		model.addAttribute("permissions", permissionList);
		List<Integer> userRoleIds=um.getRoleIdsByUserId(user.getId());
		List<Integer> userPermissionIds=um.getPermissionIdsByUserId(user.getId());
		model.addAttribute("userRoleIds", userRoleIds);
		model.addAttribute("userPermissionIds", userPermissionIds);
		return "system/user/form";
	}
	/**
	 * 新增用户
	 * @param target
	 * @param model
	 * @return
	 */
	@PostMapping("0")
	@PreAuthorize("hasPermission('base','all')")
	@Transactional
	public String add(User user,Model model,int[] permission,int[] role){
		if(user.getEnabled()==null)user.setEnabled(Boolean.FALSE);
		user.setPassword(pe.encode(user.getPassword()));
		um.insert(user);
		if(role!=null)for(int r:role)um.insertUserRole(user.getId(), r);
		if(permission!=null)for(int p:permission)um.insertUserPermission(user.getId(), p);
		return "redirect:index";
	}
	/**
	 * 修改用户信息
	 * @param target
	 * @param model
	 * @return
	 */
	@PostMapping("{id}")
	@PreAuthorize("hasPermission('base','all')")
	@Transactional
	public String update(User user,Model model,int[] permission,int[] role){
		if(user.getEnabled()==null)user.setEnabled(Boolean.FALSE);
		List<Integer> roleIds=um.getRoleIdsByUserId(user.getId());
		List<Integer> permissionIds=um.getPermissionIdsByUserId(user.getId());
		um.updateInfo(user);
		if(role==null)role=new int[0];
		if(permission==null)permission=new int[0];
		for(int r:role){
			if(!roleIds.contains(r))um.insertUserRole(user.getId(), r);
		}
		Arrays.stream(role).forEach(i->{
			roleIds.remove((Integer)i);
		});
		for(int r:roleIds){
			um.deleteUserRole(user.getId(), r);
		}
		for(int p:permission){
			if(!permissionIds.contains(p))um.insertUserPermission(user.getId(), p);
		}
		Arrays.stream(permission).forEach(i->{
			permissionIds.remove((Integer)i);
		});
		for(int p:permissionIds){
			um.deleteUserPermission(user.getId(), p);
		}
		return "redirect:index";
	}
	/**
	 * 删除用户
	 * @param id
	 * @return
	 */
	@GetMapping("{id}/delete")
	@PreAuthorize("hasPermission('base','all')")
	@Transactional
	public String delete(@PathVariable("id")int id){
		um.deleteUserAllRole(id);
		um.deleteUserAllPermission(id);
		um.deleteUser(id);
		return "redirect:../index";
	}
	
	/**
	 * 检验登录名是否存在
	 * @param param
	 * @return
	 */
	@GetMapping("{type}/checkUsername")
	@ResponseBody
	@PreAuthorize("hasPermission('base','all')")
	public void checkNode(String username){
		User u=um.getByLoginName(username);
		if(u!=null)throw new ApiException(ExceptionType.DUPLICATE_USERNAME);
	}
}
